<?php

declare(strict_types=1);
/**
 * 集中数据处理类 为自定义标签处理返回数据
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2022/5/10.
 */

namespace Zane\View\Service;

use Illuminate\Support\Facades\Cache;

class ReadHandle
{
    private $action;
    private $transfer;
    private $result;
    private $k;

    public function __construct($action, Transfer $transfer)
    {
        $action = lcfirst($action);
        $this->transfer = $transfer;
        $this->k = $action;
        $this->action = config('view.tag_action.'.$action);

        if ($this->action) {
            $this->loadData();
        }
    }

    public static function read($action, Transfer $transfer): array
    {
        return (new self($action, $transfer))->getResult();
    }

    private function getResult(): array
    {
        return (array) $this->result;
    }

    private function loadData(): void
    {
        if ($this->cache() && $this->loadCacheData()) {
            return;
        }
        $this->result = $this->getClass()->{$this->getMethod()}($this->transfer);
        $this->setCacheData($this->result);
    }

    private function getClass()
    {
        $class = $this->action;
        if (\is_array($this->action)) {
            $class = $this->action['class'];
        }

        return app($class);
    }

    private function getMethod()
    {
        return $this->action['method'] ?? 'read';
    }

    // 是否配置缓存
    private function cache(): bool
    {
        return isset($this->action['cache']);
    }

    private function loadCacheData(): bool
    {
        $result = Cache::get($this->getKey());
        if ($result) {
            $this->result = unserialize($result);

            return true;
        }

        return false;
    }

    private function setCacheData($result): void
    {
        if (!blank($result) || !$this->cache()) {
            return;
        }
        Cache::put($this->getKey(), serialize($result), $this->action['cache']);
    }

    private function getKey(): string
    {
        return 'view:'.$this->k.':'.(string) $this->transfer;
    }
}
